﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Web;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using TMM.Common;

namespace TMM
{
    public partial class TMMViewController : UIViewController
    {
        private UIBarButtonItem actionsButton;
        private bool areActionsButtonVisible, areNotificationsVisible;
        private UIBarButtonItem backButton;
        private UIImagePickerController imagePicker;
        private UIBarButtonItem menuButton;
        private UIBarButtonItem notificationsButton;
        private UIButton notificationsInnerButton;

        public TMMViewController() : base("TMMViewController", null)
        {
        }

        public LocalDataBase LocalData { get; private set; }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            LocalData = new LocalData();

            InitializeInterface();
            UIApplication.SharedApplication.SetStatusBarHidden(true, false);

            webView.ShouldStartLoad += HandleStartLoad;

            if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
            {
                UIUserNotificationType userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
                var userNoticationSettings = UIUserNotificationSettings.GetSettingsForTypes(userNotificationTypes, new NSSet(new string[] { }));

                UIApplication.SharedApplication.RegisterUserNotificationSettings(userNoticationSettings);
                UIApplication.SharedApplication.RegisterForRemoteNotifications();
            }
            else
            {
                UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge;
                UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
            }
        }

        public void RefreshNotificationsCount()
        {
            notificationsInnerButton.SetTitle(UIApplication.SharedApplication.ApplicationIconBadgeNumber.ToString(CultureInfo.InvariantCulture), UIControlState.Normal);
            areNotificationsVisible = UIApplication.SharedApplication.ApplicationIconBadgeNumber > 0;
            ToggleActionsButton();
        }

        public void LoadApplication(string serverCode)
        {
            string applicationUrl = Constants.ApplicationUrl;

            string serverToLoad = string.IsNullOrWhiteSpace(serverCode) ? LocalData.GetLastServer() : serverCode;
            if (!string.IsNullOrWhiteSpace(serverToLoad))
            {
                Server server = new ServersManager().GetServer(serverToLoad);
                applicationUrl = server != null ? server.ApplicationUrl.ToString() : Constants.ApplicationUrl;
            }

            string appVersion = NibBundle.ObjectForInfoDictionary("CFBundleShortVersionString").ToString();
            applicationUrl += string.Format("?appv={0}", appVersion);
            if (!string.IsNullOrWhiteSpace(DeviceInfo.Id))
                applicationUrl += string.Format("&deviceId={0}", HttpUtility.UrlEncode(DeviceInfo.Id));

            webView.LoadRequest(new NSUrlRequest(new NSUrl(applicationUrl)));
        }

        public bool HandleStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
        {
            if (!request.Url.Scheme.Equals("javascriptcall"))
                return true;

            string command = HttpUtility.UrlDecode(request.Url.ResourceSpecifier);

            string[] parameters = GetParameters(command);

            if (request.Url.ResourceSpecifier.StartsWith("setPageTitle"))
            {
                NavigationItem.Title = parameters[0];
            }
            else if (request.Url.ResourceSpecifier.StartsWith("disconnect"))
            {
                UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
                NavigationController.SetNavigationBarHidden(true, false);
                webView.Reload();
            }
            else if (request.Url.ResourceSpecifier.StartsWith("setBackbtnVisible"))
            {
                bool isVisible = parameters[0].Equals("true");
                NavigationItem.LeftBarButtonItem = isVisible ? backButton : menuButton;
            }
            else if (request.Url.ResourceSpecifier.StartsWith("setModuleAction"))
            {
                SetActionsImage(parameters[0]);
            }
            else if (request.Url.ResourceSpecifier.StartsWith("setNotifications"))
            {
                int nr = 0;
                int.TryParse(parameters[0], out nr);
                UIApplication.SharedApplication.ApplicationIconBadgeNumber = nr;
                notificationsInnerButton.SetTitle(nr.ToString(), UIControlState.Normal);
                areNotificationsVisible = nr > 0;
                ToggleActionsButton();
            }
            else if (request.Url.ResourceSpecifier.StartsWith("updateApplication"))
            {
                string url = parameters[0];
                ShowUpdateApplicationDialog(url);
            }
            else if (request.Url.ResourceSpecifier.StartsWith("menuVisible"))
            {
                bool isVisible = parameters[0].Equals("true");
                NavigationController.SetNavigationBarHidden(!isVisible, false);
            }
            else if (request.Url.ResourceSpecifier.StartsWith("getDeviceId"))
            {
                if (!string.IsNullOrWhiteSpace(DeviceInfo.Id))
                {
                    var setDeviceCommand = string.Format("setDeviceId('{0}');", DeviceInfo.Id);
                    webView.EvaluateJavascript(setDeviceCommand);
                }
            }
            else if (request.Url.ResourceSpecifier.StartsWith("showPictureSourceDialog"))
            {
                ShowPhotoDialog();
            }
            else if (request.Url.ResourceSpecifier.StartsWith("setServer"))
            {
                LocalData.SetLastServerCode(parameters[0]);
            }
            else if (request.Url.ResourceSpecifier.StartsWith("loadApplication"))
            {
                string serverCode = parameters[0];
                string username = parameters[1];
                string password = parameters[2];

                if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password))
                    LocalData.SetAuthenticationData(new AuthenticationData
                    {
                        ServerCode = serverCode.ToLower().Trim(),
                        Username = username.Trim(),
                        Password = password.Trim()
                    });
                LoadApplication(serverCode);
            }
            else if (request.Url.ResourceSpecifier.StartsWith("getConnectionData"))
            {
                Authenticate();
            }

            webView.EvaluateJavascript(string.Format("commandExecuted('{0}')",
                HttpUtility.UrlDecode(request.Url.Description)));

            return false;
        }

        public void Authenticate()
        {
            AuthenticationData authData = LocalData.GetAuthenticationData();
            if (authData == null)
                return;

            string command = string.Format("authenticate('{0}','{1}','{2}')", authData.ServerCode, authData.Username, authData.Password);

            LocalData.ResetAuthenticationData();

            webView.EvaluateJavascript(command);
        }

        private void ShowPhotoDialog()
        {
            var actionSheet = new UIActionSheet("Alegeti sursa", null, "Renuntare", "Camera", new[] {"Galerie foto"})
            {
                Style = UIActionSheetStyle.Default
            };

            actionSheet.Clicked += delegate(object sender, UIButtonEventArgs args)
            {
                if (args.ButtonIndex == 2)
                    return;

                imagePicker = new UIImagePickerController();

                if (args.ButtonIndex == 0)
                {
                    imagePicker.SourceType = UIImagePickerControllerSourceType.Camera;
                }
                else if (args.ButtonIndex == 1)
                {
                    imagePicker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
                }

                imagePicker.MediaTypes =
                    UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary);
                imagePicker.FinishedPickingMedia += Handle_FinishedPickingMedia;
                imagePicker.Canceled += Handle_Canceled;
                NavigationController.PresentViewController(imagePicker, true, null);
            };

            actionSheet.ShowInView(View);
        }

        protected void Handle_FinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs e)
        {
            var originalImage = e.Info[UIImagePickerController.OriginalImage] as UIImage;
            imagePicker.DismissViewController(true, null);

            string picName = string.Format("pic_{0}.png", DateTime.Now.ToString("yyyyMMddHHmmss"));

            UIImage image = ResizeImage(originalImage);

            byte[] data = null;
            using (NSData imageData = image.AsPNG())
            {
                data = new Byte[imageData.Length];
                Marshal.Copy(imageData.Bytes, data, 0, Convert.ToInt32(imageData.Length));
            }

            string dataString = Convert.ToBase64String(data);
            webView.EvaluateJavascript(string.Format("IphonePic('{0}', '{1}')", dataString, picName));
        }

        private UIImage ResizeImage(UIImage image)
        {
            float rectWidth = 250.0f;
            float rectHeight = 250.0f;
            if (image.Size.Height > rectHeight)
            {
                float ratio = rectHeight/image.Size.Height;
                rectWidth = ratio*image.Size.Width;
            }
            if (rectWidth > 250.0f)
            {
                float ratio = 250.0f/rectWidth;
                rectHeight = ratio*image.Size.Height;
                rectWidth = 250.0f;
            }

            var rect = new RectangleF(0, 0, rectWidth, rectHeight);
            UIGraphics.BeginImageContextWithOptions(rect.Size, false, 0.0f);
            image.Draw(rect);
            image = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();

            return image;
        }

        private void Handle_Canceled(object sender, EventArgs e)
        {
            imagePicker.DismissViewController(true, null);
        }

        private void ShowUpdateApplicationDialog(string url)
        {
            if (string.IsNullOrWhiteSpace(url))
                return;

            var actionSheet = new UIActionSheet("Este necesara actualizarea la o noua versiune a aplicatiei.", null,
                null, "OK", null)
            {
                Style = UIActionSheetStyle.Default
            };
            actionSheet.Clicked += delegate { UIApplication.SharedApplication.OpenUrl(new NSUrl(url)); };

            actionSheet.ShowInView(View);
        }

        private void SetActionsImage(string action)
        {
            if (string.IsNullOrWhiteSpace(action) || action.ToLower() == "none")
            {
                areActionsButtonVisible = false;
                ToggleActionsButton();
                return;
            }

            action = action.ToLower();

            string image = string.Empty;
            if (action == "addrequest")
                image = "toolbar-add-request.png";
            else if (action == "more")
                image = "toolbar-more.png";
            else if (action == "search")
                image = "toolbar-search.png";
            else if (action == "delete")
                image = "toolbar-delete.png";
            else if (action == "edit")
                image = "toolbar-edit.png";
            else if (action == "history")
                image = "toolbar-history.png";
            else if (action == "save")
                image = "toolbar-save.png";
            else if (action == "refresh")
                image = "toolbar-refresh.png";
            else if (action == "camera")
                image = "toolbar-camera.png";
            else if (action == "email")
                image = "toolbar-email.png";
            else if (action == "settings")
                image = "toolbar-settings.png";
            else if (action == "upload")
                image = "toolbar-upload.png";

            actionsButton = new UIBarButtonItem(
                UIImage.FromFile(image),
                UIBarButtonItemStyle.Plain,
                (s, e) => { webView.EvaluateJavascript("beginModuleAction();"); }
                );

            areActionsButtonVisible = true;
            ToggleActionsButton();
        }

        private string[] GetParameters(string command)
        {
            if (string.IsNullOrWhiteSpace(command))
                return null;

            var splitters = new[] {'(', ')'};

            string[] data = command.Split(splitters, int.MaxValue);
            return data.Count() > 0 ? data[1].Split(new[] {','}, int.MaxValue) : null;
        }

        private void InitializeInterface()
        {
            View.BackgroundColor = UIColor.White;

            var menuButtonPlain = new UIButton(UIButtonType.Custom);
            menuButtonPlain.Frame = new RectangleF(0, 0, 30, 30);
            menuButtonPlain.SetImage(UIImage.FromFile("menu.png"), UIControlState.Normal);
            menuButton = new UIBarButtonItem(menuButtonPlain);
            menuButtonPlain.TouchUpInside +=
                (object sender, EventArgs e) => { webView.EvaluateJavascript("showLeftMenu();"); };

            backButton = new UIBarButtonItem("Inapoi", UIBarButtonItemStyle.Bordered,
                (s, e) => { webView.EvaluateJavascript("goBack();"); });

            NavigationItem.LeftBarButtonItem = menuButton;

            BuildNotificationsButton();

            actionsButton = new UIBarButtonItem(
                UIImage.FromFile("toolbar-more.png"),
                UIBarButtonItemStyle.Plain,
                (s, e) => { webView.EvaluateJavascript("beginModuleAction();"); }
                );

            areActionsButtonVisible = false;
            ToggleActionsButton();
        }

        private void ToggleActionsButton()
        {
            var buttons = new List<UIBarButtonItem>();

            if (areNotificationsVisible)
                buttons.Add(notificationsButton);
            if (areActionsButtonVisible)
                buttons.Add(actionsButton);

            NavigationItem.SetRightBarButtonItems(buttons.ToArray(), false);
        }

        private void BuildNotificationsButton()
        {
            notificationsInnerButton = new UIButton(UIButtonType.Custom);
            notificationsInnerButton.Frame = new RectangleF(0, 0, 26, 26);
            notificationsInnerButton.BackgroundColor = UIColor.Red;
            notificationsInnerButton.Layer.CornerRadius = 5.0f;

            notificationsButton = new UIBarButtonItem(notificationsInnerButton);

            notificationsInnerButton.TouchUpInside +=
                (sender, e) => { webView.EvaluateJavascript("showNotifications();"); };
        }

        public void UpdateUnreadNotification(int ccdId)
        {
            string command = "window.setTimeout(function(){ updateUnreadNotifications('{" + ccdId + "}');}, 1);";
            webView.EvaluateJavascript(command);
        }
    }
}